package snafu.implementation.agents;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

import snafu.framework.actions.AbstractAction;
import snafu.framework.actions.AbstractReaction;
import snafu.framework.agents.AgentBrain;
import snafu.framework.agents.AgentState;
import snafu.framework.agents.AgentStateItself;
import snafu.framework.objects.WorldObject;
import snafu.framework.view.Access;
import snafu.framework.worlds.WorldMap;
import snafu.implementation.actions.create.CreateIntention;
import snafu.implementation.actions.create.CreateIntentionItself;
import snafu.implementation.actions.drop.random.RandomDropIntention;
import snafu.implementation.actions.drop.random.RandomDropIntentionItself;
import snafu.implementation.objects.banana.Banana;
import snafu.implementation.objects.banana.BananaItself;
import snafu.implementation.states.literals.color.ColorLiteralItself;
import snafu.implementation.states.literals.depth.DepthLiteralItself;
import snafu.implementation.states.literals.have.HaveLiteral;
import snafu.implementation.states.literals.walk.WalkableLiteralItself;

public class BananaTree extends AgentBrain {
	@Override
	public AgentStateItself getInitialState() {
		AgentStateItself state = new AgentStateItself();
		// literals
		state.addLiteral(new ColorLiteralItself(new Color(50, 106, 0), Access.PUBLIC));
		state.addLiteral(new DepthLiteralItself(1, Access.PUBLIC));
		state.addLiteral(new WalkableLiteralItself(false, Access.PUBLIC));

		// intentions
		state.setIntention(new CreateIntentionItself(Access.PRIVATE));
		state.setIntention(new RandomDropIntentionItself(Access.PRIVATE));
		return state;
	}

	@Override
	public AbstractAction act(WorldMap perception, AgentState state) {
		// create banana
		CreateIntention createIntention = state.getIntention(CreateIntention.class);
		if (Math.random() < 0.01 && createIntention != null) {
			AbstractAction action = createIntention.createAction(new BananaItself()); 
			return action;
		}

		// drop bananas
		RandomDropIntention dropIntention = state.getIntention(RandomDropIntention.class);
		if (dropIntention != null) {
			// get all bananas from state
			List<WorldObject> bananas = new ArrayList<WorldObject>();
			for (HaveLiteral literal : state.getLiterals(HaveLiteral.class)) {
				if (Banana.class.isAssignableFrom(literal.getValue().getClass())) {
					bananas.add((Banana) literal.getValue());
				}
			}
			// generate random not dropped number
			int notDropping = (int) (Math.random() * bananas.size());
			// drop bananas
			if (notDropping < bananas.size()) {
				for (int i = 0; i < notDropping; i++) {
					bananas.remove(0);
				}
				return dropIntention.createAction(bananas);
			}
		}

		// do nothing
		return null;
	}
	
	@Override
	public AbstractReaction react(AbstractAction action) {
		return null;
	}
	
	@Override
	public String output() {
		return "BananaTree";
	}
}
